import React, {useContext, useEffect, useMemo} from 'react';
import { Layout, Button, notification } from 'antd';

import showOutputIcon from '../../../../assets/svgs/show-output-icon.svg';

import './ServoPanel.css';
import { SerialContext } from '../../context/SerialContext';

import { useServoDataStore } from '../../stores/serialStore';
import SerialConnectComponent from '../../components/SerialConnectComponent';
import ServoInputIdComponent from '../../components/ServoInputIdComponent';
import ServoListComponent from '../../components/ServoListComponent';
import CommandOutputComponent from '../../components/CommandOutputComponent';
import {getUniqueItemsById} from "../../utils/arrayHelper";

import {isStopAccidentally} from '../../utils/command';

const { Header, Footer, Content, Sider } = Layout;

const ServoPanel: React.FC = () => {
  const {
    searchResults,
    isVisible,
    commandOutput,
    clearCommandOutput,
    clearMessages,
    addDebugMessage,
    handleShow,
    handleHide,
    toggleVisibility,
    addCommandOutput,
    addSearchResult,
  } = useServoDataStore();

  // 在组件内计算派生状态
  const searchResultsWithServo = useMemo(() => {
    return getUniqueItemsById(searchResults)
  }, [searchResults]);

  const { serialState, setSerialState } = useContext(SerialContext)!;

  useEffect(() => {
    const ipc = window.electron.ipcRenderer;

    const receiveSearch = (
      _event: any,
      baud: number,
      servo_id: number,
      error_code: number
    ) => {
      addSearchResult(baud, servo_id, error_code);
    };

    const searchError = (
        _event: any,
        payload: { message: string; stack?: string; code?: string; command?: string; args?: any[] },
    ) => {
      setSerialState((prev) => ({ ...prev, isSerialSearch: false }));

      // 非正常停止搜索
      const searchInterrupt = isStopAccidentally(payload.message)
      if (searchInterrupt) {
        notification.error({
          message: '搜索错误',
          description: payload.message || '未知错误',
          duration: 5,
        });
      }
    };

    const searchOutput = (_event: any, data: string) => {
      addCommandOutput(data);
    };

    const firmwareOutput = (_event: any, data: string) => {
      addCommandOutput(data);
    };

    ipc.on('ipc-notification-receive-search', receiveSearch);
    ipc.on('search-error', searchError);
    ipc.on('search-output', searchOutput);
    ipc.on('firmware-output', firmwareOutput);

    return () => {
      ipc.off('ipc-notification-receive-search', receiveSearch);
      ipc.off('search-error', searchError);
      ipc.off('search-output', searchOutput);
      ipc.off('firmware-output', firmwareOutput);
    };
  }, [addSearchResult, addCommandOutput, setSerialState]);

  // 搜索启动
  const searchStartUp = () => {
    clearMessages();
    handleShow();
    clearCommandOutput();
  };

  // 升级启动
  const servoUpgrade = () => {
    handleShow();
    clearCommandOutput();
  };

  return (
    <Layout>
      <Content className="servo-container">
        {/* 头部 */}
        <div className="servo-header">
          <SerialConnectComponent
            showSearchButton={true}
            onSearchStartUp={searchStartUp}
          />
        </div>

        {/* 中间部分 */}
        <Content className="servo-content">
          <ServoInputIdComponent />
          <ServoListComponent
            searchResults={searchResultsWithServo}
            onServoUpgrade={servoUpgrade}
          />
        </Content>

        {/* 底部 */}
        <div className="servo-footer">
          {isVisible && (
            <CommandOutputComponent
              output={commandOutput}
              onHideOutput={handleHide}
            />
          )}
        </div>
      </Content>

      {/* 右侧边栏 */}
      <Sider className="servo-aside" width={50}>
        <div className="servo-aside-inner">
          <div className="servo-aside-bottom">
            <Button
              type="text"
              onClick={toggleVisibility}
              className="servo-aside-button"
              aria-label="显示输出"
            >
              <img src={showOutputIcon} alt="显示输出" />
            </Button>
          </div>
        </div>
      </Sider>
    </Layout>
  );
};

export default ServoPanel;
